package com.titaniume.java;

import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;

import  com.titaniume.java.Employee.Status;

/**
 *@program: java8
 *@description:
 *  3.终止操作
 *  规约和收集
 *
 *@author: renfei.huang
 *@create: 2021-10-29 16:51
 */
public class TestStreamAPI4 {


    List<Employee> emps = Arrays.asList(
            new Employee(102, "李四", 79, 6666.66, Status.BUSY),
            new Employee(101, "张三", 18, 9999.99, Status.FREE),
            new Employee(103, "王五", 28, 3333.33, Status.VOCATION),
            new Employee(104, "赵六", 8, 7777.77, Status.BUSY),
            new Employee(104, "赵六", 8, 7777.77, Status.FREE),
            new Employee(104, "赵六", 8, 7777.77, Status.FREE),
            new Employee(105, "田七", 38, 5555.55, Status.BUSY)
    );


    	/*
		归约
		reduce(T identity, BinaryOperator) / reduce(BinaryOperator) ——可以将流中元素反复结合起来，得到一个值。
	 */

    @Test
    public void test1(){
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);

        Integer sum = list.stream()
                .reduce(0, (x, y) -> x + y);
        System.out.println(sum);


        System.out.println("---------------------------");


        Optional<Double> op = emps.stream()
                .map(Employee::getSalary)
                .reduce(Double::sum);
        System.out.println(op.get());

    }

    //需求：搜索名字中 "六"的出现次数
    @Test
    public void  test2(){
        Optional<Integer> op2 = emps.stream()
                .map(Employee::getName)
                .flatMap(TestStreamAPI2::filterCharacter)
                .map((ch) -> {
                    if (ch.equals('六')) {
                        return 1;
                    } else {
                        return 0;
                    }
                }).reduce(Integer::sum);
        System.out.println(op2.get());
    }

    //collect——将流转换为其他形式。接收一个 Collector接口的实现，用于给Stream中元素做汇总的方法

    @Test
    public void  test3(){

        //返回name list
        List<String> list = emps.stream()
                .map(Employee::getName)
                .collect(Collectors.toList());
        list.forEach(System.out::println);
        System.out.println("---------------------------");

        //返回name set
        Set<String> set = emps.stream()
                .map(Employee::getName)
                .collect(Collectors.toSet());
        set.forEach(System.out::println);
        System.out.println("---------------------------");

        //返回name 任意容器
        HashSet<String> hs = emps.stream()
                .map(Employee::getName)
                .collect(Collectors.toCollection(HashSet::new));
        hs.forEach(System.out::println);

    }


    @Test
    public  void test4(){
        //总数
        Long count = emps.stream()
                .collect(Collectors.counting());
        System.out.println(count);
        System.out.println("---------------------------");

        //平均值
        Double avg = emps.stream()
                .collect(Collectors.averagingDouble(Employee::getSalary));
        System.out.println(avg);
        System.out.println("---------------------------");


        //总和
        Double sum = emps.stream()
                .collect(Collectors.summingDouble(Employee::getSalary));
        System.out.println(sum);
        System.out.println("---------------------------");


        //最大值
        Optional<Employee> max = emps.stream().max((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
        System.out.println(max);
        System.out.println("---------------------------");


        //最小值
        Optional<Double> min = emps.stream()
                .map(Employee::getSalary).min(Double::compare);
        System.out.println(min);


    }


    //分组
    @Test
    public  void test5(){
        Map<Status, List<Employee>> map = emps.stream()
                .collect(Collectors.groupingBy(Employee::getStatus));
        System.out.println(map);
    }

    //多级分组
    @Test
    public void  test6(){
        Map<Status, Map<String, List<Employee>>> map = emps.stream()
                .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {
                    if (e.getAge() <= 35) {
                        return "青年";
                    } else if (e.getAge() <= 50) {
                        return "中年";
                    } else {
                        return "老年";
                    }
                })));
        System.out.println(map);
    }


    //分区
    @Test
    public void  test7(){
        Map<Boolean, List<Employee>> map = emps.stream()
                .collect(Collectors.partitioningBy((e) -> e.getSalary() > 8000));
        System.out.println(map);
    }



    //返回某个对象的聚合操作
    @Test
    public void  test8(){
        DoubleSummaryStatistics dos = emps.stream()
                .collect(Collectors.summarizingDouble(Employee::getSalary));
        System.out.println(dos.getMax   ());
        System.out.println(dos.getAverage());
        System.out.println(dos.getSum());
    }


    //字符串拼接 joining 拼接字符串,首,尾
    @Test
    public void  test9(){
        String str = emps.stream()
                .map(Employee::getName)
                .collect(Collectors.joining(",","<",">"));
        System.out.println(str);
    }

}
